import re
from typing import List, Dict
"""
二、 step1：数据预处理（清理 + 结构化）
原始数据存在「格式冗余（换行 / 空格）、部分法条内容不完整（如第 42 条）」问题，需先处理：
1. 文本格式清理
去除 content 中的多余换行、空格，统一标点符号，确保文本规整。
示例（原始第 1 条）：
"第一条\n为了完善劳动合同制度，明确劳动合同双方当事人的权利和义务，\n保护劳动者的合法权益，构建和发展和谐稳定的劳动关系，制定本法。"
清理后：
"第一条 为了完善劳动合同制度，明确劳动合同双方当事人的权利和义务，保护劳动者的合法权益，构建和发展和谐稳定的劳动关系，制定本法。"
2. 修正不完整数据
原始数据中第 42 条内容被拆分（“第四十二条 劳动者有下列情形之一的，用人单位不得依照本法第四十条、” 与 “第四十一条的规定解除劳动合同：...”），需合并为完整法条：
"第四十二条 劳动者有下列情形之一的，用人单位不得依照本法第四十条、第四十一条的规定解除劳动合同：（一）从事接触职业病危害作业的劳动者未进行离岗前职业健康检查，或者疑似职业病病人在诊断或者医学观察期间的；（二）在本单位患职业病或者因工负伤并被确认丧失或者部分丧失劳动能力的；（三）患病或者非因工负伤，在规定的医疗期内的；（四）女职工在孕期、产期、哺乳期的；（五）在本单位连续工作满十五年，且距法定退休年龄不足五年的；（六）法律、行政法规规定的其他情形。"
3. 提取法条主题（新增元数据）
为每个法条添加「article_title」（主题），方便后续关键词检索（如用户搜 “试用期工资” 可快速匹配第 20 条），主题需基于法条内容精准提炼：
法条号	法条内容核心	article_title（主题）
第一条	立法目的	立法目的与依据
第二条	适用范围	劳动合同法适用范围
第十九条	试用期期限	试用期期限规定
第四十六条	经济补偿情形	经济补偿适用情形
"""

def preprocess_labor_law(raw_data: List[Dict]) -> List[Dict]:
    """
    预处理劳动合同法原始数据，包括文本清理、修正不完整法条、提取元数据

    参数:
        raw_data: 原始数据列表，每个元素为包含chapter、article_num、content的字典

    返回:
        预处理后的结构化数据列表，每个元素包含vector_text、metadata、id
    """
    corrected_data = _correct_incomplete_articles(raw_data)
    processed_results = []

    for item in corrected_data:
        chapter = item['chapter'].strip()
        article_num = re.sub(r'[^\u4e00-\u9fa5\d]', '', item['article_num'].strip())
        content = item['content'].strip()

        content_clean = _clean_content(content, article_num)
        chapter_code = _extract_chapter_code(chapter)
        article_num_code = _extract_article_code(article_num)  # 核心修复点
        article_title = _generate_article_title(article_num, content_clean)

        vector_text = f"中华人民共和国劳动合同法 {chapter} {article_num} {content_clean}"
        article_id = f"labor_law_{article_num_code}"

        processed_results.append({
            "vector_text": vector_text,
            "metadata": {
                "law_name": "中华人民共和国劳动合同法",
                "chapter": chapter,
                "chapter_code": chapter_code,
                "article_num": article_num,
                "article_num_code": article_num_code,
                "article_title": article_title,
                "content_clean": content_clean
            },
            "id": article_id
        })

    return processed_results


def _correct_incomplete_articles(raw_data: List[Dict]) -> List[Dict]:
    """修正被拆分的法条（如第42条）"""
    corrected = [item.copy() for item in raw_data]

    article_42_part1 = None
    article_42_part2 = None

    for i, item in enumerate(corrected):
        if item['article_num'].strip() == '第四十二条':
            article_42_part1 = i
        if item['article_num'].strip() == '第四十一条' and '第四十一条的规定解除劳动合同' in item['content']:
            article_42_part2 = i

    if article_42_part1 is not None and article_42_part2 is not None:
        part1_content = corrected[article_42_part1]['content'].replace('第四十二条', '').strip()
        part2_content = corrected[article_42_part2]['content'].replace('第四十一条', '').strip()
        merged_content = f"第四十二条 {part1_content}{part2_content}"
        corrected[article_42_part1]['content'] = merged_content
        del corrected[article_42_part2]

    return corrected


# ... existing code ...
def _clean_content(content: str, article_num: str) -> str:
    """
    清理内容中的多余换行、空格和重复的法条编号

    该函数用于清洗法条内容文本，去除多余的空白字符并移除开头可能存在的法条编号，
    使内容更加整洁规范。

    Args:
        content (str): 待清理的法条内容文本
        article_num (str): 法条编号，用于从内容开头移除重复的编号

    Returns:
        str: 清理后的法条内容文本
    """
    cleaned = re.sub(r'\s+', ' ', content).strip()
    # 移除内容开头可能存在的法条编号及其后面的空白字符
    cleaned = re.sub(rf'^{re.escape(article_num)}\s*', '', cleaned)
    return cleaned.strip()


# ... existing code ...


# ... existing code ...
def _extract_chapter_code(chapter: str) -> str:
    """
    从章节名称提取数字编码

    该函数通过正则表达式匹配章节名称中的中文或阿拉伯数字章节号，
    并将其转换为两位数的数字编码格式。

    Args:
        chapter (str): 包含章节信息的字符串，如"第一章"、"第二章"等

    Returns:
        str: 两位数的数字编码，如"01"、"02"等，如果未匹配到则返回"00"
    """
    # 中文数字到阿拉伯数字的映射表
    chinese_num_map = {'一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8}
    # 使用正则表达式匹配"第X章"模式，其中X可以是中文数字或阿拉伯数字
    match = re.search(r'第([一二三四五六七八\d]+)章', chapter)
    if match:
        num_str = match.group(1)
        # 如果匹配到的是中文数字，则从映射表中获取对应的阿拉伯数字
        if num_str in chinese_num_map:
            return f"{chinese_num_map[num_str]:02d}"
        # 如果匹配到的是阿拉伯数字，则直接转换为整数并格式化
        if num_str.isdigit():
            return f"{int(num_str):02d}"
    # 未匹配到任何章节号时返回默认值"00"
    return "00"


# ... existing code ...


def _extract_article_code(article_num: str) -> str:
    """从法条编号提取数字编码（增强中文数字处理）"""
    # 优先匹配阿拉伯数字（如"第16条"）
    match = re.search(r'第(\d+)条', article_num)
    if match:
        return f"{int(match.group(1)):03d}"

    # 处理中文数字（重点修复"十"系列数字解析）
    chinese_num_map = {
        '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9,
        '十': 10, '十一': 11, '十二': 12, '十三': 13, '十四': 14, '十五': 15,
        '十六': 16, '十七': 17, '十八': 18, '十九': 19, '二十': 20,
        '二十一': 21, '二十二': 22, '二十三': 23, '二十四': 24, '二十五': 25,
        '二十六': 26, '二十七': 27, '二十八': 28, '二十九': 29, '三十': 30,
        '三十一': 31, '三十二': 32, '三十三': 33, '三十四': 34, '三十五': 35,
        '三十六': 36, '三十七': 37, '三十八': 38, '三十九': 39, '四十': 40,
        '四十一': 41, '四十二': 42, '四十三': 43, '四十四': 44, '四十五': 45,
        '四十六': 46, '四十七': 47, '四十八': 48, '四十九': 49, '五十': 50,
        '五十一': 51, '五十二': 52, '五十三': 53, '五十四': 54, '五十五': 55,
        '五十六': 56, '五十七': 57, '五十八': 58, '五十九': 59, '六十': 60,
        '六十一': 61, '六十二': 62, '六十三': 63, '六十四': 64, '六十五': 65,
        '六十六': 66, '六十七': 67, '六十八': 68, '六十九': 69, '七十': 70,
        '七十一': 71, '七十二': 72, '七十三': 73, '七十四': 74, '七十五': 75,
        '七十六': 76, '七十七': 77, '七十八': 78, '七十九': 79, '八十': 80,
        '八十一': 81, '八十二': 82, '八十三': 83, '八十四': 84, '八十五': 85,
        '八十六': 86, '八十七': 87, '八十八': 88, '八十九': 89, '九十': 90,
        '九十一': 91, '九十二': 92, '九十三': 93, '九十四': 94, '九十五': 95,
        '九十六': 96, '九十七': 97, '九十八': 98
    }

    # 提取"第X条"中的X部分
    match_chinese = re.search(r'第(.+)条', article_num)
    if match_chinese:
        num_str = match_chinese.group(1)
        if num_str in chinese_num_map:
            return f"{chinese_num_map[num_str]:03d}"

    return "000"  # 异常情况


def _generate_article_title(article_num: str, content: str) -> str:
    """基于法条内容生成主题"""
    keyword_map = {
        '第一条': '立法目的与依据',
        '第二条': '适用范围',
        '第三条': '订立原则',
        '第四条': '规章制度制定',
        '第十条': '书面劳动合同订立要求',
        '第十四条': '无固定期限劳动合同',
        '第十七条': '劳动合同必备条款',
        '第十九条': '试用期规定',
        '第二十条': '试用期工资标准',
        '第三十八条': '劳动者解除劳动合同的情形',
        '第三十九条': '用人单位解除劳动合同的情形',
        '第四十六条': '经济补偿适用情形',
        '第四十七条': '经济补偿计算标准',
        '第八十二条': '未签劳动合同的法律责任',
    }

    if article_num in keyword_map:
        return keyword_map[article_num]

    content_truncated = content[:20].strip()
    return content_truncated + ('...' if len(content) > 20 else '')


# 使用示例
if __name__ == "__main__":
    sample_raw_data = [
        {
            'chapter': '第二章 劳动合同的订立',
            'article_num': '第十六条',
            'content': '第十六条 劳动合同由用人单位与劳动者协商一致，并经用人单位与劳动者 在劳动合同文本上签字或者盖章生效。 劳动合同文本由用人单位和劳动者各执一份。'
        },
        {
            'chapter': '第二章 劳动合同的订立',
            'article_num': '第十七条',
            'content': '第十七条 劳动合同应当具备以下条款： （一）用人单位的名称、住所和法定代表人或者主要负责人； （二）劳动者的姓名、住址和居民身份证或者其他有效身份证件号码；'
        }
    ]

    processed = preprocess_labor_law(sample_raw_data)
    print(processed)
    for item in processed:
        print(f"ID: {item['id']}")
        print(f"法条编号: {item['metadata']['article_num_code']}")
        print(f"向量文本: {item['vector_text'][:100]}...\n")
